#include "connection_map.h"
#include "ikcp.h"

namespace KCP {
CConnectionMap::CConnectionMap() {
	m_connections.clear();
}

CConnectionMap::~CConnectionMap() {
	Stop();
}

CConnection* CConnectionMap::FindConnection(uint32 conv) {
	auto iter = m_connections.find(conv);
	if (iter == m_connections.end()) {
		return nullptr;
	} else {
		return iter->second;
	}
}

void CConnectionMap::Update(int64 clockTime) {
	CConnection* conn = nullptr;
	for (auto iter = m_connections.begin(); iter != m_connections.end();) {
		if ((conn = iter->second)) {
			// update data.
			conn->update(clockTime);

			// time out check.
			if (conn->isTimeout()) {
				CConnection::release(conn);
				m_connections.erase(iter++);
			} else {
				iter++;
			}
		} else {
			ADebug("find invalid connection");
		}
	}
}

CConnection* CConnectionMap::Create(CConnectionMgr &manager, 
	uint32 conv, const udp::endpoint& endpoint
) {
	CConnection *conn = CConnection::create(manager, conv, endpoint);
	m_connections[conv] = conn;
	return conn;
}

bool CConnectionMap::CheckConnect(const udp::endpoint &ep) const {
	for (const auto &e : m_connections) {
		if (e.second->get_endpoint() == ep) {
			return true;
		}
	}
	return false;
}

uint32 CConnectionMap::GetNextConv() {
	static uint32 static_cur_conv = 0;
	static_cur_conv++;
	return static_cur_conv;
}

void CConnectionMap::Stop() {
	for (auto &e : m_connections) {
		CConnection::release(e.second);
	}
	m_connections.clear();
}

void CConnectionMap::Remove(uint32 conv) {
	m_connections.erase(conv);
}
}